package methodInvoke;

public class DynamicDispatch {
    static abstract class Human{
        public void sayHello(){
            System.out.println("Human");
        }
    }
    static class Man extends Human{
        public void sayHello(){
            System.out.println("Man");
        }
    }
    static class Woman extends Human{
        public void sayHello(){
            System.out.println("Man");
        }
    }

    /**
     *    #4 = Methodref          #11.#24        // methodInvoke/DynamicDispatch$Human.sayHello:()V
     *    #11 = Class              #28            // methodInvoke/DynamicDispatch$Human
     *    #28 = Utf8               methodInvoke/DynamicDispatch$Human
     *    #24 = NameAndType        #29:#14        // sayHello:()V
     *    #29 = Utf8               sayHello
     *    #14 = Utf8               ()V
     *
     *   public static void main(java.lang.String[]);
     *     descriptor: ([Ljava/lang/String;)V
     *     flags: (0x0009) ACC_PUBLIC, ACC_STATIC
     *     Code:
     *       stack=2, locals=2, args_size=1
     *          0: new           #2                  // class methodInvoke/DynamicDispatch$Man
     *          3: dup
     *          4: invokespecial #3                  // Method methodInvoke/DynamicDispatch$Man."<init>":()V
     *          7: astore_1
     *          8: aload_1
     *          9: invokevirtual #4                  // Method methodInvoke/DynamicDispatch$Human.sayHello:()V
     *         12: aload_1
     *         13: invokevirtual #4                  // Method methodInvoke/DynamicDispatch$Human.sayHello:()V
     *         16: return
     *       LineNumberTable:
     *         line 21: 0
     *         line 22: 8
     *         line 23: 12
     *         line 24: 16
     *
     *  注意这里的 9: invokevirtual #4 13: invokevirtual #4    都是 invokevirtual 需要在运行时确定真正的调用方法的直接引用
     *
     * @param args
     */
    public static void main(String[] args) {
        Human man = new Man();
        man.sayHello();
        ((Human)man).sayHello();
    }
}
